home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyo (Python 2.5)
-
- import cStringIO
- import random
- import struct
- import sys
- import time
- import dns.exception as dns
- import dns.flags as dns
- import dns.name as dns
- import dns.opcode as dns
- import dns.rcode as dns
- import dns.rdata as dns
- import dns.rdataclass as dns
- import dns.rdatatype as dns
- import dns.rrset as dns
- import dns.renderer as dns
- import dns.tsig as dns
-
- class ShortHeader(dns.exception.FormError):
- pass
-
-
- class TrailingJunk(dns.exception.FormError):
- pass
-
-
- class UnknownHeaderField(dns.exception.DNSException):
- pass
-
-
- class BadEDNS(dns.exception.FormError):
- pass
-
-
- class BadTSIG(dns.exception.FormError):
- pass
-
-
- class UnknownTSIGKey(dns.exception.DNSException):
- pass
-
-
- class Message(object):
-
- def __init__(self, id = None):
- if id is None:
- self.id = random.randint(0, 65535)
- else:
- self.id = id
- self.flags = 0
- self.question = []
- self.answer = []
- self.authority = []
- self.additional = []
- self.edns = -1
- self.ednsflags = 0
- self.payload = 0
- self.request_payload = 0
- self.keyring = None
- self.keyname = None
- self.request_mac = ''
- self.other_data = ''
- self.tsig_error = 0
- self.fudge = 300
- self.original_id = self.id
- self.mac = ''
- self.xfr = False
- self.origin = None
- self.tsig_ctx = None
- self.had_tsig = False
- self.multi = False
- self.first = True
- self.index = { }
-
-
- def __repr__(self):
- return '<DNS message, ID ' + `self.id` + '>'
-
-
- def __str__(self):
- return self.to_text()
-
-
- def to_text(self, origin = None, relativize = True, **kw):
- s = cStringIO.StringIO()
- print >>s, 'id %d' % self.id
- print >>s, 'opcode %s' % dns.opcode.to_text(dns.opcode.from_flags(self.flags))
- rc = dns.rcode.from_flags(self.flags, self.ednsflags)
- print >>s, 'rcode %s' % dns.rcode.to_text(rc)
- print >>s, 'flags %s' % dns.flags.to_text(self.flags)
- if self.edns >= 0:
- print >>s, 'edns %s' % self.edns
- if self.ednsflags != 0:
- print >>s, 'eflags %s' % dns.flags.edns_to_text(self.ednsflags)
-
- print >>s, 'payload', self.payload
-
- is_update = dns.opcode.is_update(self.flags)
- if is_update:
- print >>s, ';ZONE'
- else:
- print >>s, ';QUESTION'
- for rrset in self.question:
- print >>s, rrset.to_text(origin, relativize, **kw)
-
- if is_update:
- print >>s, ';PREREQ'
- else:
- print >>s, ';ANSWER'
- for rrset in self.answer:
- print >>s, rrset.to_text(origin, relativize, **kw)
-
- if is_update:
- print >>s, ';UPDATE'
- else:
- print >>s, ';AUTHORITY'
- for rrset in self.authority:
- print >>s, rrset.to_text(origin, relativize, **kw)
-
- print >>s, ';ADDITIONAL'
- for rrset in self.additional:
- print >>s, rrset.to_text(origin, relativize, **kw)
-
- return s.getvalue()[:-1]
-
-
- def __eq__(self, other):
- if not isinstance(other, Message):
- return False
-
- if self.id != other.id:
- return False
-
- if self.flags != other.flags:
- return False
-
- for n in self.question:
- if n not in other.question:
- return False
- continue
-
- for n in other.question:
- if n not in self.question:
- return False
- continue
-
- for n in self.answer:
- if n not in other.answer:
- return False
- continue
-
- for n in other.answer:
- if n not in self.answer:
- return False
- continue
-
- for n in self.authority:
- if n not in other.authority:
- return False
- continue
-
- for n in other.authority:
- if n not in self.authority:
- return False
- continue
-
- return True
-
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
-
- def is_response(self, other):
- if other.flags & dns.flags.QR == 0 and self.id != other.id or dns.opcode.from_flags(self.flags) != dns.opcode.from_flags(other.flags):
- return False
-
- if dns.rcode.from_flags(other.flags, other.ednsflags) != dns.rcode.NOERROR:
- return True
-
- if dns.opcode.is_update(self.flags):
- return True
-
- for n in self.question:
- if n not in other.question:
- return False
- continue
-
- for n in other.question:
- if n not in self.question:
- return False
- continue
-
- return True
-
-
- def section_number(self, section):
- if section is self.question:
- return 0
- elif section is self.answer:
- return 1
- elif section is self.authority:
- return 2
- elif section is self.additional:
- return 3
- else:
- raise ValueError, 'unknown section'
-
-
- def find_rrset(self, section, name, rdclass, rdtype, covers = dns.rdatatype.NONE, deleting = None, create = False, force_unique = False):
- key = (self.section_number(section), name, rdclass, rdtype, covers, deleting)
- if not force_unique:
- if self.index is not None:
- rrset = self.index.get(key)
- if rrset is not None:
- return rrset
-
- else:
- for rrset in section:
- if rrset.match(name, rdclass, rdtype, covers, deleting):
- return rrset
- continue
-
-
- if not create:
- raise KeyError
-
- rrset = dns.rrset.RRset(name, rdclass, rdtype, covers, deleting)
- section.append(rrset)
- if self.index is not None:
- self.index[key] = rrset
-
- return rrset
-
-
- def get_rrset(self, section, name, rdclass, rdtype, covers = dns.rdatatype.NONE, deleting = None, create = False, force_unique = False):
-
- try:
- rrset = self.find_rrset(section, name, rdclass, rdtype, covers, deleting, create, force_unique)
- except KeyError:
- rrset = None
-
- return rrset
-
-
- def to_wire(self, origin = None, max_size = 0, **kw):
- if max_size == 0:
- if self.request_payload != 0:
- max_size = self.request_payload
- else:
- max_size = 65535
-
- if max_size < 512:
- max_size = 512
- elif max_size > 65535:
- max_size = 65535
-
- r = dns.renderer.Renderer(self.id, self.flags, max_size, origin)
- for rrset in self.question:
- r.add_question(rrset.name, rrset.rdtype, rrset.rdclass)
-
- for rrset in self.answer:
- r.add_rrset(dns.renderer.ANSWER, rrset, **kw)
-
- for rrset in self.authority:
- r.add_rrset(dns.renderer.AUTHORITY, rrset, **kw)
-
- if self.edns >= 0:
- r.add_edns(self.edns, self.ednsflags, self.payload)
-
- for rrset in self.additional:
- r.add_rrset(dns.renderer.ADDITIONAL, rrset, **kw)
-
- r.write_header()
- if self.keyname is not None:
- r.add_tsig(self.keyname, self.keyring[self.keyname], self.fudge, self.original_id, self.tsig_error, self.other_data, self.request_mac)
- self.mac = r.mac
-
- return r.get_wire()
-
-
- def use_tsig(self, keyring, keyname = None, fudge = 300, original_id = None, tsig_error = 0, other_data = ''):
- self.keyring = keyring
- if keyname is None:
- self.keyname = self.keyring.keys()[0]
- elif isinstance(keyname, (str, unicode)):
- keyname = dns.name.from_text(keyname)
-
- self.keyname = keyname
- self.fudge = fudge
- if original_id is None:
- self.original_id = self.id
- else:
- self.original_id = original_id
- self.tsig_error = tsig_error
- self.other_data = other_data
-
-
- def use_edns(self, edns = 0, ednsflags = 0, payload = 1280, request_payload = None):
- if edns is None or edns is False:
- edns = -1
-
- if edns is True:
- edns = 0
-
- if request_payload is None:
- request_payload = payload
-
- if edns < 0:
- ednsflags = 0
- payload = 0
- request_payload = 0
- else:
- ednsflags &= 0xFF00FFFFL
- ednsflags |= edns << 16
- self.edns = edns
- self.ednsflags = ednsflags
- self.payload = payload
- self.request_payload = request_payload
-
-
- def want_dnssec(self, wanted = True):
- if wanted:
- if self.edns < 0:
- self.use_edns()
-
- self.ednsflags |= dns.flags.DO
- elif self.edns >= 0:
- self.ednsflags &= ~(dns.flags.DO)
-
-
-
- def rcode(self):
- return dns.rcode.from_flags(self.flags, self.ednsflags)
-
-
- def set_rcode(self, rcode):
- (value, evalue) = dns.rcode.to_flags(rcode)
- self.flags &= 65520
- self.flags |= value
- self.ednsflags &= 0xFFFFFFL
- self.ednsflags |= evalue
-
-
- def opcode(self):
- return dns.opcode.from_flags(self.flags)
-
-
- def set_opcode(self, opcode):
- self.flags &= 34815
- self.flags |= dns.opcode.to_flags(opcode)
-
-
-
- class _WireReader(object):
-
- def __init__(self, wire, message, question_only = False):
- self.wire = wire
- self.message = message
- self.current = 0
- self.updating = False
- self.zone_rdclass = dns.rdataclass.IN
- self.question_only = question_only
-
-
- def _get_question(self, qcount):
- if self.updating and qcount > 1:
- raise dns.exception.FormError
-
- for i in xrange(0, qcount):
- (qname, used) = dns.name.from_wire(self.wire, self.current)
- if self.message.origin is not None:
- qname = qname.relativize(self.message.origin)
-
- self.current = self.current + used
- (rdtype, rdclass) = struct.unpack('!HH', self.wire[self.current:self.current + 4])
- self.current = self.current + 4
- self.message.find_rrset(self.message.question, qname, rdclass, rdtype, create = True, force_unique = True)
- if self.updating:
- self.zone_rdclass = rdclass
- continue
-
-
-
- def _get_section(self, section, count):
- if self.updating:
- force_unique = True
- else:
- force_unique = False
- seen_opt = False
- for i in xrange(0, count):
- rr_start = self.current
- (name, used) = dns.name.from_wire(self.wire, self.current)
- if self.message.origin is not None:
- name = name.relativize(self.message.origin)
-
- self.current = self.current + used
- (rdtype, rdclass, ttl, rdlen) = struct.unpack('!HHIH', self.wire[self.current:self.current + 10])
- self.current = self.current + 10
- if rdtype == dns.rdatatype.OPT:
- if section is not self.message.additional or seen_opt:
- raise BadEDNS
-
- self.message.payload = rdclass
- self.message.ednsflags = ttl
- self.message.edns = (ttl & 16711680) >> 16
- seen_opt = True
- elif rdtype == dns.rdatatype.TSIG:
- if not section is self.message.additional and i == count - 1:
- raise BadTSIG
-
- if self.message.keyring is None:
- raise UnknownTSIGKey, 'got signed message without keyring'
-
- secret = self.message.keyring.get(name)
- if secret is None:
- raise UnknownTSIGKey, "key '%s' unknown" % name
-
- self.message.tsig_ctx = dns.tsig.validate(self.wire, name, secret, int(time.time()), self.message.request_mac, rr_start, self.current, rdlen, self.message.tsig_ctx, self.message.multi, self.message.first)
- self.message.had_tsig = True
- elif ttl < 0:
- ttl = 0
-
- if self.updating:
- if rdclass == dns.rdataclass.ANY or rdclass == dns.rdataclass.NONE:
- deleting = rdclass
- rdclass = self.zone_rdclass
- else:
- deleting = None
- if deleting == dns.rdataclass.ANY:
- covers = dns.rdatatype.NONE
- rd = None
- else:
- rd = dns.rdata.from_wire(rdclass, rdtype, self.wire, self.current, rdlen, self.message.origin)
- covers = rd.covers()
- if self.message.xfr and rdtype == dns.rdatatype.SOA:
- force_unique = True
-
- rrset = self.message.find_rrset(section, name, rdclass, rdtype, covers, deleting, True, force_unique)
- if rd is not None:
- rrset.add(rd, ttl)
-
- self.current = self.current + rdlen
-
-
-
- def read(self):
- l = len(self.wire)
- if l < 12:
- raise ShortHeader
-
- (self.message.id, self.message.flags, qcount, ancount, aucount, adcount) = struct.unpack('!HHHHHH', self.wire[:12])
- self.current = 12
- if dns.opcode.is_update(self.message.flags):
- self.updating = True
-
- self._get_question(qcount)
- if self.question_only:
- return None
-
- self._get_section(self.message.answer, ancount)
- self._get_section(self.message.authority, aucount)
- self._get_section(self.message.additional, adcount)
- if self.current != l:
- raise TrailingJunk
-
- if self.message.multi and self.message.tsig_ctx and not (self.message.had_tsig):
- self.message.tsig_ctx.update(self.wire)
-
-
-
-
- def from_wire(wire, keyring = None, request_mac = '', xfr = False, origin = None, tsig_ctx = None, multi = False, first = True, question_only = False):
- m = Message(id = 0)
- m.keyring = keyring
- m.request_mac = request_mac
- m.xfr = xfr
- m.origin = origin
- m.tsig_ctx = tsig_ctx
- m.multi = multi
- m.first = first
- reader = _WireReader(wire, m, question_only)
- reader.read()
- return m
-
-
- class _TextReader(object):
-
- def __init__(self, text, message):
- self.message = message
- self.tok = dns.tokenizer.Tokenizer(text)
- self.last_name = None
- self.zone_rdclass = dns.rdataclass.IN
- self.updating = False
-
-
- def _header_line(self, section):
- (ttype, what) = self.tok.get()
- if what == 'id':
- self.message.id = self.tok.get_int()
- elif what == 'flags':
- while True:
- token = self.tok.get()
- if token[0] != dns.tokenizer.IDENTIFIER:
- self.tok.unget(token)
- break
-
- self.message.flags = self.message.flags | dns.flags.from_text(token[1])
- if dns.opcode.is_update(self.message.flags):
- self.updating = True
-
- elif what == 'edns':
- self.message.edns = self.tok.get_int()
- self.message.ednsflags = self.message.ednsflags | self.message.edns << 16
- elif what == 'eflags':
- if self.message.edns < 0:
- self.message.edns = 0
-
- while True:
- token = self.tok.get()
- if token[0] != dns.tokenizer.IDENTIFIER:
- self.tok.unget(token)
- break
-
- self.message.ednsflags = self.message.ednsflags | dns.flags.edns_from_text(token[1])
- elif what == 'payload':
- self.message.payload = self.tok.get_int()
- if self.message.edns < 0:
- self.message.edns = 0
-
- elif what == 'opcode':
- text = self.tok.get_string()
- self.message.flags = self.message.flags | dns.opcode.to_flags(dns.opcode.from_text(text))
- elif what == 'rcode':
- text = self.tok.get_string()
- self.message.set_rcode(dns.rcode.from_text(text))
- else:
- raise UnknownHeaderField
- self.tok.get_eol()
-
-
- def _question_line(self, section):
- token = self.tok.get(want_leading = True)
- if token[0] != dns.tokenizer.WHITESPACE:
- self.last_name = dns.name.from_text(token[1], None)
-
- name = self.last_name
- token = self.tok.get()
- if token[0] != dns.tokenizer.IDENTIFIER:
- raise dns.exception.SyntaxError
-
-
- try:
- rdclass = dns.rdataclass.from_text(token[1])
- token = self.tok.get()
- if token[0] != dns.tokenizer.IDENTIFIER:
- raise dns.exception.SyntaxError
- except dns.exception.SyntaxError:
- raise dns.exception.SyntaxError
- except:
- rdclass = dns.rdataclass.IN
-
- rdtype = dns.rdatatype.from_text(token[1])
- self.message.find_rrset(self.message.question, name, rdclass, rdtype, create = True, force_unique = True)
- if self.updating:
- self.zone_rdclass = rdclass
-
- self.tok.get_eol()
-
-
- def _rr_line(self, section):
- deleting = None
- token = self.tok.get(want_leading = True)
- if token[0] != dns.tokenizer.WHITESPACE:
- self.last_name = dns.name.from_text(token[1], None)
-
- name = self.last_name
- token = self.tok.get()
- if token[0] != dns.tokenizer.IDENTIFIER:
- raise dns.exception.SyntaxError
-
-
- try:
- ttl = int(token[1], 0)
- token = self.tok.get()
- if token[0] != dns.tokenizer.IDENTIFIER:
- raise dns.exception.SyntaxError
- except dns.exception.SyntaxError:
- raise dns.exception.SyntaxError
- except:
- ttl = 0
-
-
- try:
- rdclass = dns.rdataclass.from_text(token[1])
- token = self.tok.get()
- if token[0] != dns.tokenizer.IDENTIFIER:
- raise dns.exception.SyntaxError
-
- if rdclass == dns.rdataclass.ANY or rdclass == dns.rdataclass.NONE:
- deleting = rdclass
- rdclass = self.zone_rdclass
- except dns.exception.SyntaxError:
- raise dns.exception.SyntaxError
- except:
- rdclass = dns.rdataclass.IN
-
- rdtype = dns.rdatatype.from_text(token[1])
- token = self.tok.get()
- if token[0] != dns.tokenizer.EOL and token[0] != dns.tokenizer.EOF:
- self.tok.unget(token)
- rd = dns.rdata.from_text(rdclass, rdtype, self.tok, None)
- covers = rd.covers()
- else:
- rd = None
- covers = dns.rdatatype.NONE
- rrset = self.message.find_rrset(section, name, rdclass, rdtype, covers, deleting, True, self.updating)
- if rd is not None:
- rrset.add(rd, ttl)
-
-
-
- def read(self):
- line_method = self._header_line
- section = None
- while None:
- token = self.tok.get(True, True)
- if token[0] == dns.tokenizer.EOL or token[0] == dns.tokenizer.EOF:
- break
-
- if token[0] == dns.tokenizer.COMMENT:
- u = token[1].upper()
- if u == 'HEADER':
- line_method = self._header_line
- elif u == 'QUESTION' or u == 'ZONE':
- line_method = self._question_line
- section = self.message.question
- elif u == 'ANSWER' or u == 'PREREQ':
- line_method = self._rr_line
- section = self.message.answer
- elif u == 'AUTHORITY' or u == 'UPDATE':
- line_method = self._rr_line
- section = self.message.authority
- elif u == 'ADDITIONAL':
- line_method = self._rr_line
- section = self.message.additional
-
- self.tok.get_eol()
- continue
-
- line_method(section)
- continue
- return None
-
-
-
- def from_text(text):
- m = Message()
- reader = _TextReader(text, m)
- reader.read()
- return m
-
-
- def from_file(f):
- if sys.hexversion >= 33751040:
- str_type = basestring
- opts = 'rU'
- else:
- str_type = str
- opts = 'r'
- if isinstance(f, str_type):
- f = file(f, opts)
- want_close = True
- else:
- want_close = False
-
- try:
- m = from_text(f)
- finally:
- if want_close:
- f.close()
-
-
- return m
-
-
- def make_query(qname, rdtype, rdclass = dns.rdataclass.IN, use_edns = None, want_dnssec = False):
- if isinstance(qname, (str, unicode)):
- qname = dns.name.from_text(qname)
-
- if isinstance(rdtype, str):
- rdtype = dns.rdatatype.from_text(rdtype)
-
- if isinstance(rdclass, str):
- rdclass = dns.rdataclass.from_text(rdclass)
-
- m = Message()
- m.flags |= dns.flags.RD
- m.find_rrset(m.question, qname, rdclass, rdtype, create = True, force_unique = True)
- m.use_edns(use_edns)
- m.want_dnssec(want_dnssec)
- return m
-
-
- def make_response(query, recursion_available = False, our_payload = 8192):
- if query.flags & dns.flags.QR:
- raise dns.exception.FormError, 'specified query message is not a query'
-
- response = dns.message.Message(query.id)
- response.flags = dns.flags.QR | query.flags & dns.flags.RD
- if recursion_available:
- response.flags |= dns.flags.RA
-
- response.set_opcode(query.opcode())
- response.question = list(query.question)
- if query.edns >= 0:
- response.use_edns(0, 0, our_payload, query.payload)
-
- if query.keyname is not None:
- response.keyname = query.keyname
- response.keyring = query.keyring
- response.request_mac = query.mac
-
- return response
-
-